﻿using Newtonsoft.Json;
using RestSharp;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace FAMailUtils.MailGun
{
    public class StatsItem
    {
        public string Event { get; set; }
        public decimal total_count { get; set; }
        public string id { get; set; }
        //public string tags { get; set; }
    }
    public class StatsResult
    {
        public bool isGetOK { get; set; }
        public string message { get; set; }
        public decimal total_count { get; set; }
        public List<StatsItem> items { get; set; }
    }
    public class SendResult
    {
        public decimal item_id { get; set; }
        public bool IsSent { get; set; }
        public string message { get; set; }
        public string id { get; set; }
    }
    public class LogItem
    {
        public string Event { get; set; }
        public string timestamp { get; set; }
        public string from { get { return message.headers.from; } }
        public string to { get { return message.headers.to; } }
        public string messageId { get { return message.headers.message_id; } }
        public message message { get; set; }
        public string severity { get; set; }
        public string reason { get; set; }
    }
    public class TrackingLogItem
    {
        public string Event { get; set; }
        public string timestamp { get; set; }
        public string ip { get; set; }
        public string recipient { get; set; }
        public string messageId { get { return message.headers.message_id; } }
        public message message { get; set; }
        //public string severity { get; set; }
        //public string reason { get; set; }
    }

    public class message
    {
        public header headers { get; set; }
    }
    public class header
    {
        public string to { get; set; }
        public string from { get; set; }
        [JsonProperty("message-id")]
        public string message_id { get; set; }
        public string subject { get; set; }
    }
    public class Logs
    {
        public List<LogItem> items { get; set; }
        public paging paging { get; set; }
        public bool isGetOK { get; set; }
        public string message { get; set; }
    }
    public class TrackingLogs
    {
        public List<TrackingLogItem> items { get; set; }
        public paging paging { get; set; }
        public bool isGetOK { get; set; }
        public string message { get; set; }
    }
    public class paging
    {
        public string next { get; set; }
        public string previous { get; set; }
    }
    public class SendMail
    {
        string ApiKey;
        public SendMail(string ApiKey)
        {
            this.ApiKey = ApiKey;
        }
        public SendResult SendSimpleMessage(string domain, string senderName, string sender, List<string> recieves, string subject, string body)
        {
            SendResult result = new SendResult();
            try
            {
                if (domain.ToLower() == "gmail.com") domain = "smtp.gmail.com";
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                        new HttpBasicAuthenticator("api",
                                                   ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                                    domain, ParameterType.UrlSegment);
                request.Resource = "{domain}/messages";
                request.AddParameter("from", string.Format("{0} <{1}>", senderName, sender));
                foreach (var recieve in recieves)
                    request.AddParameter("to", recieve);
                request.AddParameter("subject", subject);
                request.AddParameter("text", body);
                request.Method = Method.POST;
                IRestResponse response = client.Execute(request);

                result = Newtonsoft.Json.JsonConvert.DeserializeObject<SendResult>(response.Content);
                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                    result.IsSent = true;
            }
            catch (Exception ex) { result.IsSent = false; result.message = ex.Message; }
            return result;
        }
        public SendResult SendHtmlMessage(string domain, string senderName, string sender, List<string> recieves, string subject, string body)
        {
            SendResult result = new SendResult();
            try
            {
                if (domain.ToLower() == "gmail.com") domain = "smtp.gmail.com";
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                        new HttpBasicAuthenticator("api",
                                                   ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                                    domain, ParameterType.UrlSegment);
                request.Resource = "{domain}/messages";
                request.AddParameter("from", string.Format("{0} <{1}>", senderName, sender));

                foreach (var recieve in recieves)
                    request.AddParameter("to", recieve);
                request.AddParameter("subject", subject);
                request.AddParameter("html", body);
                request.AddParameter("o:tracking", true);
                request.AddParameter("o:tracking-clicks", true);
                request.AddParameter("o:tracking-opens", true);
                request.Method = Method.POST;
                IRestResponse response = client.Execute(request);
                result = Newtonsoft.Json.JsonConvert.DeserializeObject<SendResult>(response.Content);
                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                    result.IsSent = true;
            }
            catch (Exception ex) { result.IsSent = false; result.message = ex.Message; }
            return result;
        }
        public SendResult SendHtmlMessage(string domain, string senderName, string sender, string recieve, string subject, string body, bool trackingClick)
        {
            SendResult result = new SendResult();
            try
            {
                if (domain.ToLower() == "gmail.com") domain = "smtp.gmail.com";
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                        new HttpBasicAuthenticator("api",
                                                   ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                                    domain, ParameterType.UrlSegment);
                request.Resource = "{domain}/messages";
                request.AddParameter("from", string.Format("{0} <{1}>", senderName, sender));

                request.AddParameter("to", recieve);
                request.AddParameter("subject", subject);
                request.AddParameter("reply", sender);
                request.AddParameter("html", body);
                if (trackingClick)
                {
                    request.AddParameter("o:tracking", true);
                    request.AddParameter("o:tracking-clicks", true);
                    request.AddParameter("o:tracking-opens", true);
                }
                request.Method = Method.POST;
                IRestResponse response = client.Execute(request);
                result = Newtonsoft.Json.JsonConvert.DeserializeObject<SendResult>(response.Content);
                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                    result.IsSent = true;
            }
            catch (Exception ex) { result.IsSent = false; result.message = ex.Message; }
            return result;
        }
        public SendResult SendHtmlMessage(string domain, string senderName, string sender, string recieve, string cc, string bcc, string subject, string body, bool trackingClick, List<string> fileAttches)
        {
            SendResult result = new SendResult();
            try
            {
                if (domain.ToLower() == "gmail.com") domain = "smtp.gmail.com";
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                        new HttpBasicAuthenticator("api",
                                                   ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                                    domain, ParameterType.UrlSegment);
                request.Resource = "{domain}/messages";
                request.AddParameter("from", string.Format("{0} <{1}>", senderName, sender));

                request.AddParameter("to", recieve);
                if (cc.Trim() != "")
                    request.AddParameter("cc", cc);
                if (bcc.Trim() != "")
                    request.AddParameter("bcc", bcc);
                request.AddParameter("subject", subject);
                request.AddParameter("reply", sender);
                request.AddParameter("html", body);
                if (trackingClick)
                {
                    request.AddParameter("o:tracking", true);
                    request.AddParameter("o:tracking-clicks", true);
                    request.AddParameter("o:tracking-opens", true);
                }
                foreach (string file in fileAttches)
                {
                    request.AddFile("attachment", file);
                }
                request.Method = Method.POST;
                IRestResponse response = client.Execute(request);
                result = Newtonsoft.Json.JsonConvert.DeserializeObject<SendResult>(response.Content);
                if (response.StatusCode == System.Net.HttpStatusCode.OK)
                    result.IsSent = true;
            }
            catch (Exception ex) { result.IsSent = false; result.message = ex.Message; }
            return result;
        }
        public StatsResult GetStats(string domainName)
        {
            StatsResult result = new StatsResult();
            try
            {
                if (domainName.ToLower() == "gmail.com") domainName = "smtp.gmail.com";
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                        new HttpBasicAuthenticator("api",
                                                   ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                                     domainName, ParameterType.UrlSegment);
                request.Resource = "{domain}/stats";
                request.AddParameter("event", "sent");
                //The email recipient opened the email and enabled image viewing. Open tracking must be enabled in the Mailgun control panel, and the CNAME record must be pointing to mailgun.org.
                request.AddParameter("event", "opened");
                request.AddParameter("event", "dropped");
                //Mailgun sent the email and it was accepted by the recipient email server.
                request.AddParameter("event", "delivered");
                //Mailgun accepted the request to send/forward the email and the message has been placed in queue.
                request.AddParameter("event", "accepted");
                //Mailgun rejected the request to send/forward the email.
                request.AddParameter("event", "rejected");
                //Mailgun could not deliver the email to the recipient email server.
                request.AddParameter("event", "failed");
                //The email recipient clicked on a link in the email. Click tracking must be enabled in the Mailgun control panel, and the CNAME record must be pointing to mailgun.org.
                request.AddParameter("event", "clicked");
                //The email recipient clicked on the unsubscribe link. Unsubscribe tracking must be enabled in the Mailgun control panel.
                request.AddParameter("event", "unsubscribed");
                //The email recipient clicked on the spam complaint button within their email client. Feedback loops enable the notification to be received by Mailgun.
                request.AddParameter("event", "complained");
                //Mailgun has stored an incoming message
                request.AddParameter("event", "stored");
                request.AddParameter("skip", 1);
                request.AddParameter("limit", 2);
                IRestResponse response = client.Execute(request);
                result = Newtonsoft.Json.JsonConvert.DeserializeObject<StatsResult>(response.Content);
                result.isGetOK = true;
            }
            catch (Exception ex) { result.isGetOK = false; result.message = ex.Message; }
            return result;
        }

        public Logs GetLogs(string domainName, int CheckResultBackCount)
        {
            Logs result = new Logs();
            try
            {
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                    new HttpBasicAuthenticator("api",
                        ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                    domainName, ParameterType.UrlSegment);
                request.Resource = "{domain}/events";
                CultureInfo cultures = CultureInfo.CreateSpecificCulture("en-US");
                request.AddParameter("begin", DateTime.Now.Date.AddDays(-1 * CheckResultBackCount).ToString("r", cultures));
                request.AddParameter("ascending", "yes");
                request.AddParameter("limit", 100);
                request.AddParameter("event", "rejected OR failed OR delivered");
                IRestResponse response = client.Execute(request);

                result = Newtonsoft.Json.JsonConvert.DeserializeObject<Logs>(response.Content);
                result.isGetOK = true;
            }
            catch (Exception ex) { result.isGetOK = false; result.message = ex.Message; }
            return result;
        }
        public TrackingLogs GetLogsTracking(string domainName, int CheckResultBackCount)
        {
            TrackingLogs result = new TrackingLogs();
            try
            {
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                    new HttpBasicAuthenticator("api",
                        ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                    domainName, ParameterType.UrlSegment);
                request.Resource = "{domain}/events";
                CultureInfo cultures = CultureInfo.CreateSpecificCulture("en-US");
                request.AddParameter("begin", DateTime.Now.Date.AddDays(-1 * CheckResultBackCount).ToString("r", cultures));
                request.AddParameter("ascending", "yes");
                request.AddParameter("limit", 100);
                request.AddParameter("event", "opened OR clicked");
                IRestResponse response = client.Execute(request);

                result = Newtonsoft.Json.JsonConvert.DeserializeObject<TrackingLogs>(response.Content);
                result.isGetOK = true;
            }
            catch (Exception ex) { result.isGetOK = false; result.message = ex.Message; }
            return result;
        }
        public Logs GetLogNextPage(string url, string domainName)
        {
            Logs result = new Logs();
            try
            {
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                        new HttpBasicAuthenticator("api",
                                                   ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                                     domainName, ParameterType.UrlSegment);
                request.Resource = "{domain}/events/" + url.Replace("https://api.mailgun.net/v2/" + domainName + "/events/", "");
                IRestResponse response = client.Execute(request);

                result = Newtonsoft.Json.JsonConvert.DeserializeObject<Logs>(response.Content);
                result.isGetOK = true;
            }
            catch (Exception ex) { result.isGetOK = false; result.message = ex.Message; }
            return result;
        }
        public TrackingLogs GetTrackingLogNextPage(string url, string domainName)
        {
            TrackingLogs result = new TrackingLogs();
            try
            {
                RestClient client = new RestClient();
                client.BaseUrl = "https://api.mailgun.net/v2";
                client.Authenticator =
                        new HttpBasicAuthenticator("api",
                                                   ApiKey);
                RestRequest request = new RestRequest();
                request.AddParameter("domain",
                                     domainName, ParameterType.UrlSegment);
                request.Resource = "{domain}/events/" + url.Replace("https://api.mailgun.net/v2/" + domainName + "/events/", "");
                IRestResponse response = client.Execute(request);

                result = Newtonsoft.Json.JsonConvert.DeserializeObject<TrackingLogs>(response.Content);
                result.isGetOK = true;
            }
            catch (Exception ex) { result.isGetOK = false; result.message = ex.Message; }
            return result;
        }
    }

}
